; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mcpu=atmega328p -O0 < %s -mtriple=avr | FileCheck --check-prefix=CHECK-MEGA %s
; RUN: llc -mattr=avrtiny -O0 < %s -mtriple=avr | FileCheck %s

define i16 @reg_copy16(i16, i16 %a) {
; CHECK-MEGA-LABEL: reg_copy16:
; CHECK-MEGA:       ; %bb.0:
; CHECK-MEGA-NEXT:    movw r24, r22
; CHECK-MEGA-NEXT:    ret
;
; CHECK-LABEL: reg_copy16:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    mov r24, r22
; CHECK-NEXT:    mov r25, r23
; CHECK-NEXT:    ret
  ret i16 %a
}

define i8 @return_zero() {
; CHECK-MEGA-LABEL: return_zero:
; CHECK-MEGA:       ; %bb.0:
; CHECK-MEGA-NEXT:    mov r24, r1
; CHECK-MEGA-NEXT:    ret
;
; CHECK-LABEL: return_zero:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    mov r24, r17
; CHECK-NEXT:    ret
  ret i8 0
}

define i8 @atomic_load8(i8* %foo) {
; CHECK-MEGA-LABEL: atomic_load8:
; CHECK-MEGA:       ; %bb.0:
; CHECK-MEGA-NEXT:    movw r26, r24
; CHECK-MEGA-NEXT:    in r0, 63
; CHECK-MEGA-NEXT:    cli
; CHECK-MEGA-NEXT:    ld r24, X
; CHECK-MEGA-NEXT:    out 63, r0
; CHECK-MEGA-NEXT:    ret
;
; CHECK-LABEL: atomic_load8:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    mov r26, r24
; CHECK-NEXT:    mov r27, r25
; CHECK-NEXT:    in r16, 63
; CHECK-NEXT:    cli
; CHECK-NEXT:    ld r24, X
; CHECK-NEXT:    out 63, r16
; CHECK-NEXT:    ret
  %val = load atomic i8, i8* %foo unordered, align 1
  ret i8 %val
}

define avr_signalcc void @signal_handler_with_asm() {
; CHECK-MEGA-LABEL: signal_handler_with_asm:
; CHECK-MEGA:       ; %bb.0:
; CHECK-MEGA-NEXT:    push r0
; CHECK-MEGA-NEXT:    in r0, 63
; CHECK-MEGA-NEXT:    push r0
; CHECK-MEGA-NEXT:    push r1
; CHECK-MEGA-NEXT:    clr r1
; CHECK-MEGA-NEXT:    push r24
; CHECK-MEGA-NEXT:    ldi r24, 3
; CHECK-MEGA-NEXT:    ;APP
; CHECK-MEGA-NEXT:    mov r24, r24
; CHECK-MEGA-NEXT:    ;NO_APP
; CHECK-MEGA-NEXT:    pop r24
; CHECK-MEGA-NEXT:    pop r1
; CHECK-MEGA-NEXT:    pop r0
; CHECK-MEGA-NEXT:    out 63, r0
; CHECK-MEGA-NEXT:    pop r0
; CHECK-MEGA-NEXT:    reti
;
; CHECK-LABEL: signal_handler_with_asm:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    push r16
; CHECK-NEXT:    in r16, 63
; CHECK-NEXT:    push r16
; CHECK-NEXT:    push r17
; CHECK-NEXT:    clr r17
; CHECK-NEXT:    push r24
; CHECK-NEXT:    ldi r24, 3
; CHECK-NEXT:    ;APP
; CHECK-NEXT:    mov r24, r24
; CHECK-NEXT:    ;NO_APP
; CHECK-NEXT:    pop r24
; CHECK-NEXT:    pop r17
; CHECK-NEXT:    pop r16
; CHECK-NEXT:    out 63, r16
; CHECK-NEXT:    pop r16
; CHECK-NEXT:    reti
  call i8 asm sideeffect "mov $0, $1", "=r,r"(i8 3) nounwind
  ret void
}

declare void @foo()

define avr_signalcc void @signal_handler_with_call() {
; CHECK-MEGA-LABEL: signal_handler_with_call:
; CHECK-MEGA:       ; %bb.0:
; CHECK-MEGA-NEXT:    push r0
; CHECK-MEGA-NEXT:    in r0, 63
; CHECK-MEGA-NEXT:    push r0
; CHECK-MEGA-NEXT:    push r1
; CHECK-MEGA-NEXT:    clr r1
; CHECK-MEGA-NEXT:    push r18
; CHECK-MEGA-NEXT:    push r19
; CHECK-MEGA-NEXT:    push r20
; CHECK-MEGA-NEXT:    push r21
; CHECK-MEGA-NEXT:    push r22
; CHECK-MEGA-NEXT:    push r23
; CHECK-MEGA-NEXT:    push r24
; CHECK-MEGA-NEXT:    push r25
; CHECK-MEGA-NEXT:    push r26
; CHECK-MEGA-NEXT:    push r27
; CHECK-MEGA-NEXT:    push r30
; CHECK-MEGA-NEXT:    push r31
; CHECK-MEGA-NEXT:    call foo
; CHECK-MEGA-NEXT:    pop r31
; CHECK-MEGA-NEXT:    pop r30
; CHECK-MEGA-NEXT:    pop r27
; CHECK-MEGA-NEXT:    pop r26
; CHECK-MEGA-NEXT:    pop r25
; CHECK-MEGA-NEXT:    pop r24
; CHECK-MEGA-NEXT:    pop r23
; CHECK-MEGA-NEXT:    pop r22
; CHECK-MEGA-NEXT:    pop r21
; CHECK-MEGA-NEXT:    pop r20
; CHECK-MEGA-NEXT:    pop r19
; CHECK-MEGA-NEXT:    pop r18
; CHECK-MEGA-NEXT:    pop r1
; CHECK-MEGA-NEXT:    pop r0
; CHECK-MEGA-NEXT:    out 63, r0
; CHECK-MEGA-NEXT:    pop r0
; CHECK-MEGA-NEXT:    reti
;
; CHECK-LABEL: signal_handler_with_call:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    push r16
; CHECK-NEXT:    in r16, 63
; CHECK-NEXT:    push r16
; CHECK-NEXT:    push r17
; CHECK-NEXT:    clr r17
; CHECK-NEXT:    push r20
; CHECK-NEXT:    push r21
; CHECK-NEXT:    push r22
; CHECK-NEXT:    push r23
; CHECK-NEXT:    push r24
; CHECK-NEXT:    push r25
; CHECK-NEXT:    push r26
; CHECK-NEXT:    push r27
; CHECK-NEXT:    push r30
; CHECK-NEXT:    push r31
; CHECK-NEXT:    rcall foo
; CHECK-NEXT:    pop r31
; CHECK-NEXT:    pop r30
; CHECK-NEXT:    pop r27
; CHECK-NEXT:    pop r26
; CHECK-NEXT:    pop r25
; CHECK-NEXT:    pop r24
; CHECK-NEXT:    pop r23
; CHECK-NEXT:    pop r22
; CHECK-NEXT:    pop r21
; CHECK-NEXT:    pop r20
; CHECK-NEXT:    pop r17
; CHECK-NEXT:    pop r16
; CHECK-NEXT:    out 63, r16
; CHECK-NEXT:    pop r16
; CHECK-NEXT:    reti
  call void @foo()
  ret void
}
